package com.bolt.support.dynamic.datasource.hibernate;

import com.bolt.support.dynamic.datasource.toolkit.DialectContextHolder;
import org.hibernate.*;
import org.hibernate.boot.model.TypeContributions;
import org.hibernate.boot.model.relational.AuxiliaryDatabaseObject;
import org.hibernate.boot.model.relational.Sequence;
import org.hibernate.dialect.ColumnAliasExtractor;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.LobMergeStrategy;
import org.hibernate.dialect.identity.IdentityColumnSupport;
import org.hibernate.dialect.lock.LockingStrategy;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.dialect.unique.UniqueDelegate;
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
import org.hibernate.engine.jdbc.env.spi.IdentifierHelperBuilder;
import org.hibernate.engine.jdbc.env.spi.NameQualifierSupport;
import org.hibernate.engine.jdbc.env.spi.SchemaNameResolver;
import org.hibernate.engine.spi.QueryParameters;
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
import org.hibernate.exception.spi.SQLExceptionConverter;
import org.hibernate.exception.spi.ViolatedConstraintNameExtracter;
import org.hibernate.hql.spi.id.MultiTableBulkIdStrategy;
import org.hibernate.loader.BatchLoadSizingStrategy;
import org.hibernate.mapping.Constraint;
import org.hibernate.mapping.ForeignKey;
import org.hibernate.mapping.Index;
import org.hibernate.mapping.Table;
import org.hibernate.persister.entity.Lockable;
import org.hibernate.procedure.spi.CallableStatementSupport;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.sql.CaseFragment;
import org.hibernate.sql.JoinFragment;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
import org.hibernate.tool.schema.spi.Exporter;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;

import java.sql.CallableStatement;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class MultiDataSourceDialect extends Dialect {


    @Override
    public void contributeTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {

        DialectContextHolder.getCurrentDialect().contributeTypes(typeContributions, serviceRegistry);
    }

    @Override
    public String getTypeName(int code) throws HibernateException {

        return DialectContextHolder.getCurrentDialect().getTypeName(code);
    }

    @Override
    public String getTypeName(int code, long length, int precision, int scale) throws HibernateException {

        return DialectContextHolder.getCurrentDialect().getTypeName(code, length, precision, scale);
    }

    @Override
    public String getCastTypeName(int code) {

        return DialectContextHolder.getCurrentDialect().getCastTypeName(code);
    }

    @Override
    public String cast(String value, int jdbcTypeCode, int length, int precision, int scale) {

        return DialectContextHolder.getCurrentDialect().cast(value, jdbcTypeCode, length, precision, scale);
    }

    @Override
    public String cast(String value, int jdbcTypeCode, int length) {

        return DialectContextHolder.getCurrentDialect().cast(value, jdbcTypeCode, length);
    }

    @Override
    public String cast(String value, int jdbcTypeCode, int precision, int scale) {

        return DialectContextHolder.getCurrentDialect().cast(value, jdbcTypeCode, precision, scale);
    }

    @Override
    public SqlTypeDescriptor remapSqlTypeDescriptor(SqlTypeDescriptor sqlTypeDescriptor) {

        return DialectContextHolder.getCurrentDialect().remapSqlTypeDescriptor(sqlTypeDescriptor);
    }

    @Override
    public LobMergeStrategy getLobMergeStrategy() {

        return DialectContextHolder.getCurrentDialect().getLobMergeStrategy();
    }

    @Override
    public String getHibernateTypeName(int code) throws HibernateException {

        return DialectContextHolder.getCurrentDialect().getHibernateTypeName(code);
    }

    @Override
    public boolean isTypeNameRegistered(String typeName) {

        return DialectContextHolder.getCurrentDialect().isTypeNameRegistered(typeName);
    }

    @Override
    public String getHibernateTypeName(int code, int length, int precision, int scale) throws HibernateException {

        return DialectContextHolder.getCurrentDialect().getHibernateTypeName(code, length, precision, scale);
    }

    @Override
    public Class getNativeIdentifierGeneratorClass() {

        return DialectContextHolder.getCurrentDialect().getNativeIdentifierGeneratorClass();
    }

    @Override
    public String getNativeIdentifierGeneratorStrategy() {

        return DialectContextHolder.getCurrentDialect().getNativeIdentifierGeneratorStrategy();
    }

    @Override
    public IdentityColumnSupport getIdentityColumnSupport() {

        return DialectContextHolder.getCurrentDialect().getIdentityColumnSupport();
    }

    @Override
    public boolean supportsSequences() {

        return DialectContextHolder.getCurrentDialect().supportsSequences();
    }

    @Override
    public boolean supportsPooledSequences() {

        return DialectContextHolder.getCurrentDialect().supportsPooledSequences();
    }

    @Override
    public String getSequenceNextValString(String sequenceName) throws MappingException {

        return DialectContextHolder.getCurrentDialect().getSequenceNextValString(sequenceName);
    }

    @Override
    public String getSelectSequenceNextValString(String sequenceName) throws MappingException {

        return DialectContextHolder.getCurrentDialect().getSelectSequenceNextValString(sequenceName);
    }

    @Override
    public String[] getCreateSequenceStrings(String sequenceName) throws MappingException {

        return DialectContextHolder.getCurrentDialect().getCreateSequenceStrings(sequenceName);
    }

    @Override
    public String[] getCreateSequenceStrings(String sequenceName, int initialValue, int incrementSize)
            throws MappingException {

        return DialectContextHolder.getCurrentDialect().getCreateSequenceStrings(sequenceName, initialValue, incrementSize);
    }

    @Override
    public String[] getDropSequenceStrings(String sequenceName) throws MappingException {

        return DialectContextHolder.getCurrentDialect().getDropSequenceStrings(sequenceName);
    }

    @Override
    public String getQuerySequencesString() {

        return DialectContextHolder.getCurrentDialect().getQuerySequencesString();
    }

    @Override
    public SequenceInformationExtractor getSequenceInformationExtractor() {

        return DialectContextHolder.getCurrentDialect().getSequenceInformationExtractor();
    }

    @Override
    public String getSelectGUIDString() {

        return DialectContextHolder.getCurrentDialect().getSelectGUIDString();
    }

    @Override
    public LimitHandler getLimitHandler() {

        return DialectContextHolder.getCurrentDialect().getLimitHandler();
    }

    @Override
    public boolean supportsLimit() {

        return DialectContextHolder.getCurrentDialect().supportsLimit();
    }

    @Override
    public boolean supportsLimitOffset() {

        return DialectContextHolder.getCurrentDialect().supportsLimitOffset();
    }

    @Override
    public boolean supportsVariableLimit() {

        return DialectContextHolder.getCurrentDialect().supportsVariableLimit();
    }

    @Override
    public boolean bindLimitParametersInReverseOrder() {

        return DialectContextHolder.getCurrentDialect().bindLimitParametersInReverseOrder();
    }

    @Override
    public boolean bindLimitParametersFirst() {

        return DialectContextHolder.getCurrentDialect().bindLimitParametersFirst();
    }

    @Override
    public boolean useMaxForLimit() {

        return DialectContextHolder.getCurrentDialect().useMaxForLimit();
    }

    @Override
    public boolean forceLimitUsage() {

        return DialectContextHolder.getCurrentDialect().forceLimitUsage();
    }

    @Override
    public String getLimitString(String query, int offset, int limit) {

        return DialectContextHolder.getCurrentDialect().getLimitString(query, offset, limit);
    }

    @Override
    public int convertToFirstRowValue(int zeroBasedFirstResult) {

        return DialectContextHolder.getCurrentDialect().convertToFirstRowValue(zeroBasedFirstResult);
    }

    @Override
    public boolean supportsLockTimeouts() {

        return DialectContextHolder.getCurrentDialect().supportsLockTimeouts();
    }

    @Override
    public boolean isLockTimeoutParameterized() {

        return DialectContextHolder.getCurrentDialect().isLockTimeoutParameterized();
    }

    @Override
    public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) {

        return DialectContextHolder.getCurrentDialect().getLockingStrategy(lockable, lockMode);
    }

    @Override
    public String getForUpdateString(LockOptions lockOptions) {

        return DialectContextHolder.getCurrentDialect().getForUpdateString(lockOptions);
    }

    @Override
    public String getForUpdateString(LockMode lockMode) {

        return DialectContextHolder.getCurrentDialect().getForUpdateString(lockMode);
    }

    @Override
    public String getForUpdateString() {

        return DialectContextHolder.getCurrentDialect().getForUpdateString();
    }

    @Override
    public String getWriteLockString(int timeout) {

        return DialectContextHolder.getCurrentDialect().getWriteLockString(timeout);
    }

    @Override
    public String getWriteLockString(String aliases, int timeout) {

        return DialectContextHolder.getCurrentDialect().getWriteLockString(aliases, timeout);
    }

    @Override
    public String getReadLockString(int timeout) {

        return DialectContextHolder.getCurrentDialect().getReadLockString(timeout);
    }

    @Override
    public String getReadLockString(String aliases, int timeout) {

        return DialectContextHolder.getCurrentDialect().getReadLockString(aliases, timeout);
    }

    @Override
    public boolean forUpdateOfColumns() {

        return DialectContextHolder.getCurrentDialect().forUpdateOfColumns();
    }

    @Override
    public boolean supportsOuterJoinForUpdate() {

        return DialectContextHolder.getCurrentDialect().supportsOuterJoinForUpdate();
    }

    @Override
    public String getForUpdateString(String aliases) {

        return DialectContextHolder.getCurrentDialect().getForUpdateString(aliases);
    }

    @Override
    public String getForUpdateString(String aliases, LockOptions lockOptions) {

        return DialectContextHolder.getCurrentDialect().getForUpdateString(aliases, lockOptions);
    }

    @Override
    public String getForUpdateNowaitString() {

        return DialectContextHolder.getCurrentDialect().getForUpdateNowaitString();
    }

    @Override
    public String getForUpdateSkipLockedString() {

        return DialectContextHolder.getCurrentDialect().getForUpdateSkipLockedString();
    }

    @Override
    public String getForUpdateNowaitString(String aliases) {

        return DialectContextHolder.getCurrentDialect().getForUpdateNowaitString(aliases);
    }

    @Override
    public String getForUpdateSkipLockedString(String aliases) {

        return DialectContextHolder.getCurrentDialect().getForUpdateSkipLockedString(aliases);
    }

    @Override
    public String appendLockHint(LockMode mode, String tableName) {

        return DialectContextHolder.getCurrentDialect().appendLockHint(mode, tableName);
    }

    @Override
    public String appendLockHint(LockOptions lockOptions, String tableName) {

        return DialectContextHolder.getCurrentDialect().appendLockHint(lockOptions, tableName);
    }

    @Override
    public String applyLocksToSql(String sql, LockOptions aliasedLockOptions, Map<String, String[]> keyColumnNames) {

        return DialectContextHolder.getCurrentDialect().applyLocksToSql(sql, aliasedLockOptions, keyColumnNames);
    }

    @Override
    public String getCreateTableString() {

        return DialectContextHolder.getCurrentDialect().getCreateTableString();
    }

    @Override
    public String getAlterTableString(String tableName) {

        return DialectContextHolder.getCurrentDialect().getAlterTableString(tableName);
    }

    @Override
    public String getCreateMultisetTableString() {

        return DialectContextHolder.getCurrentDialect().getCreateMultisetTableString();
    }

    @Override
    public MultiTableBulkIdStrategy getDefaultMultiTableBulkIdStrategy() {

        return DialectContextHolder.getCurrentDialect().getDefaultMultiTableBulkIdStrategy();
    }

    @Override
    public int registerResultSetOutParameter(CallableStatement statement, int position) throws SQLException {

        return DialectContextHolder.getCurrentDialect().registerResultSetOutParameter(statement, position);
    }

    @Override
    public int registerResultSetOutParameter(CallableStatement statement, String name) throws SQLException {

        return DialectContextHolder.getCurrentDialect().registerResultSetOutParameter(statement, name);
    }

    @Override
    public ResultSet getResultSet(CallableStatement statement) throws SQLException {

        return DialectContextHolder.getCurrentDialect().getResultSet(statement);
    }

    @Override
    public ResultSet getResultSet(CallableStatement statement, int position) throws SQLException {

        return DialectContextHolder.getCurrentDialect().getResultSet(statement, position);
    }

    @Override
    public ResultSet getResultSet(CallableStatement statement, String name) throws SQLException {

        return DialectContextHolder.getCurrentDialect().getResultSet(statement, name);
    }

    @Override
    public boolean supportsCurrentTimestampSelection() {

        return DialectContextHolder.getCurrentDialect().supportsCurrentTimestampSelection();
    }

    @Override
    public boolean isCurrentTimestampSelectStringCallable() {

        return DialectContextHolder.getCurrentDialect().isCurrentTimestampSelectStringCallable();
    }

    @Override
    public String getCurrentTimestampSelectString() {

        return DialectContextHolder.getCurrentDialect().getCurrentTimestampSelectString();
    }

    @Override
    public String getCurrentTimestampSQLFunctionName() {

        return DialectContextHolder.getCurrentDialect().getCurrentTimestampSQLFunctionName();
    }

    @Override
    public SQLExceptionConverter buildSQLExceptionConverter() {

        return DialectContextHolder.getCurrentDialect().buildSQLExceptionConverter();
    }

    @Override
    public SQLExceptionConversionDelegate buildSQLExceptionConversionDelegate() {

        return DialectContextHolder.getCurrentDialect().buildSQLExceptionConversionDelegate();
    }

    @Override
    public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {

        return DialectContextHolder.getCurrentDialect().getViolatedConstraintNameExtracter();
    }

    @Override
    public String getSelectClauseNullString(int sqlType) {

        return DialectContextHolder.getCurrentDialect().getSelectClauseNullString(sqlType);
    }

    @Override
    public boolean supportsUnionAll() {

        return DialectContextHolder.getCurrentDialect().supportsUnionAll();
    }

    @Override
    public JoinFragment createOuterJoinFragment() {

        return DialectContextHolder.getCurrentDialect().createOuterJoinFragment();
    }

    @Override
    public CaseFragment createCaseFragment() {

        return DialectContextHolder.getCurrentDialect().createCaseFragment();
    }

    @Override
    public String getNoColumnsInsertString() {

        return DialectContextHolder.getCurrentDialect().getNoColumnsInsertString();
    }

    @Override
    public String getLowercaseFunction() {

        return DialectContextHolder.getCurrentDialect().getLowercaseFunction();
    }

    @Override
    public String getCaseInsensitiveLike() {

        return DialectContextHolder.getCurrentDialect().getCaseInsensitiveLike();
    }

    @Override
    public boolean supportsCaseInsensitiveLike() {

        return DialectContextHolder.getCurrentDialect().supportsCaseInsensitiveLike();
    }

    @Override
    public String transformSelectString(String select) {

        return DialectContextHolder.getCurrentDialect().transformSelectString(select);
    }

    @Override
    public int getMaxAliasLength() {

        return DialectContextHolder.getCurrentDialect().getMaxAliasLength();
    }

    @Override
    public String toBooleanValueString(boolean bool) {

        return DialectContextHolder.getCurrentDialect().toBooleanValueString(bool);
    }

    @Override
    public Set<String> getKeywords() {

        return DialectContextHolder.getCurrentDialect().getKeywords();
    }

    @Override
    public IdentifierHelper buildIdentifierHelper(IdentifierHelperBuilder builder, DatabaseMetaData dbMetaData)
            throws SQLException {

        return DialectContextHolder.getCurrentDialect().buildIdentifierHelper(builder, dbMetaData);
    }

    @Override
    public char openQuote() {

        return DialectContextHolder.getCurrentDialect().openQuote();
    }

    @Override
    public char closeQuote() {

        return DialectContextHolder.getCurrentDialect().closeQuote();
    }

    @Override
    public Exporter<Table> getTableExporter() {

        return DialectContextHolder.getCurrentDialect().getTableExporter();
    }

    @Override
    public Exporter<Sequence> getSequenceExporter() {

        return DialectContextHolder.getCurrentDialect().getSequenceExporter();
    }

    @Override
    public Exporter<Index> getIndexExporter() {

        return DialectContextHolder.getCurrentDialect().getIndexExporter();
    }

    @Override
    public Exporter<ForeignKey> getForeignKeyExporter() {

        return DialectContextHolder.getCurrentDialect().getForeignKeyExporter();
    }

    @Override
    public Exporter<Constraint> getUniqueKeyExporter() {

        return DialectContextHolder.getCurrentDialect().getUniqueKeyExporter();
    }

    @Override
    public Exporter<AuxiliaryDatabaseObject> getAuxiliaryDatabaseObjectExporter() {

        return DialectContextHolder.getCurrentDialect().getAuxiliaryDatabaseObjectExporter();
    }

    @Override
    public boolean canCreateCatalog() {

        return DialectContextHolder.getCurrentDialect().canCreateCatalog();
    }

    @Override
    public String[] getCreateCatalogCommand(String catalogName) {

        return DialectContextHolder.getCurrentDialect().getCreateCatalogCommand(catalogName);
    }

    @Override
    public String[] getDropCatalogCommand(String catalogName) {

        return DialectContextHolder.getCurrentDialect().getDropCatalogCommand(catalogName);
    }

    @Override
    public boolean canCreateSchema() {

        return DialectContextHolder.getCurrentDialect().canCreateSchema();
    }

    @Override
    public String[] getCreateSchemaCommand(String schemaName) {

        return DialectContextHolder.getCurrentDialect().getCreateSchemaCommand(schemaName);
    }

    @Override
    public String[] getDropSchemaCommand(String schemaName) {

        return DialectContextHolder.getCurrentDialect().getDropSchemaCommand(schemaName);
    }

    @Override
    public String getCurrentSchemaCommand() {

        return DialectContextHolder.getCurrentDialect().getCurrentSchemaCommand();
    }

    @Override
    public SchemaNameResolver getSchemaNameResolver() {

        return DialectContextHolder.getCurrentDialect().getSchemaNameResolver();
    }

    @Override
    public boolean hasAlterTable() {

        return DialectContextHolder.getCurrentDialect().hasAlterTable();
    }

    @Override
    public boolean dropConstraints() {

        return DialectContextHolder.getCurrentDialect().dropConstraints();
    }

    @Override
    public boolean qualifyIndexName() {

        return DialectContextHolder.getCurrentDialect().qualifyIndexName();
    }

    @Override
    public String getAddColumnString() {

        return DialectContextHolder.getCurrentDialect().getAddColumnString();
    }

    @Override
    public String getAddColumnSuffixString() {

        return DialectContextHolder.getCurrentDialect().getAddColumnSuffixString();
    }

    @Override
    public String getDropForeignKeyString() {

        return DialectContextHolder.getCurrentDialect().getDropForeignKeyString();
    }

    @Override
    public String getTableTypeString() {

        return DialectContextHolder.getCurrentDialect().getTableTypeString();
    }

    @Override
    public String getAddForeignKeyConstraintString(String constraintName, String[] foreignKey, String referencedTable,
                                                   String[] primaryKey, boolean referencesPrimaryKey) {

        return DialectContextHolder.getCurrentDialect().getAddForeignKeyConstraintString(constraintName, foreignKey, referencedTable,
                primaryKey, referencesPrimaryKey);
    }

    @Override
    public String getAddForeignKeyConstraintString(String constraintName, String foreignKeyDefinition) {

        return DialectContextHolder.getCurrentDialect().getAddForeignKeyConstraintString(constraintName, foreignKeyDefinition);
    }

    @Override
    public String getAddPrimaryKeyConstraintString(String constraintName) {

        return DialectContextHolder.getCurrentDialect().getAddPrimaryKeyConstraintString(constraintName);
    }

    @Override
    public boolean hasSelfReferentialForeignKeyBug() {

        return DialectContextHolder.getCurrentDialect().hasSelfReferentialForeignKeyBug();
    }

    @Override
    public String getNullColumnString() {

        return DialectContextHolder.getCurrentDialect().getNullColumnString();
    }

    @Override
    public boolean supportsCommentOn() {

        return DialectContextHolder.getCurrentDialect().supportsCommentOn();
    }

    @Override
    public String getTableComment(String comment) {

        return DialectContextHolder.getCurrentDialect().getTableComment(comment);
    }

    @Override
    public String getColumnComment(String comment) {

        return DialectContextHolder.getCurrentDialect().getColumnComment(comment);
    }

    @Override
    public boolean supportsIfExistsBeforeTableName() {

        return DialectContextHolder.getCurrentDialect().supportsIfExistsBeforeTableName();
    }

    @Override
    public boolean supportsIfExistsAfterTableName() {

        return DialectContextHolder.getCurrentDialect().supportsIfExistsAfterTableName();
    }

    @Override
    public boolean supportsIfExistsBeforeConstraintName() {

        return DialectContextHolder.getCurrentDialect().supportsIfExistsBeforeConstraintName();
    }

    @Override
    public boolean supportsIfExistsAfterConstraintName() {

        return DialectContextHolder.getCurrentDialect().supportsIfExistsAfterConstraintName();
    }

    @Override
    public boolean supportsIfExistsAfterAlterTable() {

        return DialectContextHolder.getCurrentDialect().supportsIfExistsAfterAlterTable();
    }

    @Override
    public String getDropTableString(String tableName) {

        return DialectContextHolder.getCurrentDialect().getDropTableString(tableName);
    }

    @Override
    public boolean supportsColumnCheck() {

        return DialectContextHolder.getCurrentDialect().supportsColumnCheck();
    }

    @Override
    public boolean supportsTableCheck() {

        return DialectContextHolder.getCurrentDialect().supportsTableCheck();
    }

    @Override
    public boolean supportsCascadeDelete() {

        return DialectContextHolder.getCurrentDialect().supportsCascadeDelete();
    }

    @Override
    public String getCascadeConstraintsString() {

        return DialectContextHolder.getCurrentDialect().getCascadeConstraintsString();
    }

    @Override
    public String getCrossJoinSeparator() {

        return DialectContextHolder.getCurrentDialect().getCrossJoinSeparator();
    }

    @Override
    public ColumnAliasExtractor getColumnAliasExtractor() {

        return DialectContextHolder.getCurrentDialect().getColumnAliasExtractor();
    }

    @Override
    public boolean supportsEmptyInList() {

        return DialectContextHolder.getCurrentDialect().supportsEmptyInList();
    }

    @Override
    public boolean areStringComparisonsCaseInsensitive() {

        return DialectContextHolder.getCurrentDialect().areStringComparisonsCaseInsensitive();
    }

    @Override
    public boolean supportsRowValueConstructorSyntax() {

        return DialectContextHolder.getCurrentDialect().supportsRowValueConstructorSyntax();
    }

    @Override
    public boolean supportsRowValueConstructorSyntaxInInList() {

        return DialectContextHolder.getCurrentDialect().supportsRowValueConstructorSyntaxInInList();
    }

    @Override
    public boolean useInputStreamToInsertBlob() {

        return DialectContextHolder.getCurrentDialect().useInputStreamToInsertBlob();
    }

    @Override
    public boolean supportsParametersInInsertSelect() {

        return DialectContextHolder.getCurrentDialect().supportsParametersInInsertSelect();
    }

    @Override
    public boolean replaceResultVariableInOrderByClauseWithPosition() {

        return DialectContextHolder.getCurrentDialect().replaceResultVariableInOrderByClauseWithPosition();
    }

    @Override
    public String renderOrderByElement(String expression, String collation, String order, NullPrecedence nulls) {

        return DialectContextHolder.getCurrentDialect().renderOrderByElement(expression, collation, order, nulls);
    }

    @Override
    public boolean requiresCastingOfParametersInSelectClause() {

        return DialectContextHolder.getCurrentDialect().requiresCastingOfParametersInSelectClause();
    }

    @Override
    public boolean supportsResultSetPositionQueryMethodsOnForwardOnlyCursor() {

        return DialectContextHolder.getCurrentDialect().supportsResultSetPositionQueryMethodsOnForwardOnlyCursor();
    }

    @Override
    public boolean supportsCircularCascadeDeleteConstraints() {

        return DialectContextHolder.getCurrentDialect().supportsCircularCascadeDeleteConstraints();
    }

    @Override
    public boolean supportsSubselectAsInPredicateLHS() {

        return DialectContextHolder.getCurrentDialect().supportsSubselectAsInPredicateLHS();
    }

    @Override
    public boolean supportsExpectedLobUsagePattern() {

        return DialectContextHolder.getCurrentDialect().supportsExpectedLobUsagePattern();
    }

    @Override
    public boolean supportsLobValueChangePropogation() {

        return DialectContextHolder.getCurrentDialect().supportsLobValueChangePropogation();
    }

    @Override
    public boolean supportsUnboundedLobLocatorMaterialization() {

        return DialectContextHolder.getCurrentDialect().supportsUnboundedLobLocatorMaterialization();
    }

    @Override
    public boolean supportsSubqueryOnMutatingTable() {

        return DialectContextHolder.getCurrentDialect().supportsSubqueryOnMutatingTable();
    }

    @Override
    public boolean supportsExistsInSelect() {

        return DialectContextHolder.getCurrentDialect().supportsExistsInSelect();
    }

    @Override
    public boolean doesReadCommittedCauseWritersToBlockReaders() {

        return DialectContextHolder.getCurrentDialect().doesReadCommittedCauseWritersToBlockReaders();
    }

    @Override
    public boolean doesRepeatableReadCauseReadersToBlockWriters() {

        return DialectContextHolder.getCurrentDialect().doesRepeatableReadCauseReadersToBlockWriters();
    }

    @Override
    public boolean supportsBindAsCallableArgument() {

        return DialectContextHolder.getCurrentDialect().supportsBindAsCallableArgument();
    }

    @Override
    public boolean supportsTupleCounts() {

        return DialectContextHolder.getCurrentDialect().supportsTupleCounts();
    }

    @Override
    public boolean supportsTupleDistinctCounts() {

        return DialectContextHolder.getCurrentDialect().supportsTupleDistinctCounts();
    }

    @Override
    public boolean requiresParensForTupleDistinctCounts() {

        return DialectContextHolder.getCurrentDialect().requiresParensForTupleDistinctCounts();
    }

    @Override
    public int getInExpressionCountLimit() {

        return DialectContextHolder.getCurrentDialect().getInExpressionCountLimit();
    }

    @Override
    public boolean forceLobAsLastValue() {

        return DialectContextHolder.getCurrentDialect().forceLobAsLastValue();
    }

    @Override
    public boolean useFollowOnLocking() {

        return DialectContextHolder.getCurrentDialect().useFollowOnLocking();
    }

    @Override
    public boolean useFollowOnLocking(QueryParameters parameters) {

        return DialectContextHolder.getCurrentDialect().useFollowOnLocking(parameters);
    }

    @Override
    public String getNotExpression(String expression) {

        return DialectContextHolder.getCurrentDialect().getNotExpression(expression);
    }

    @Override
    public UniqueDelegate getUniqueDelegate() {

        return DialectContextHolder.getCurrentDialect().getUniqueDelegate();
    }

    @Override
    public boolean supportsUnique() {

        return DialectContextHolder.getCurrentDialect().supportsUnique();
    }

    @Override
    public boolean supportsUniqueConstraintInCreateAlterTable() {

        return DialectContextHolder.getCurrentDialect().supportsUniqueConstraintInCreateAlterTable();
    }

    @Override
    public String getAddUniqueConstraintString(String constraintName) {

        return DialectContextHolder.getCurrentDialect().getAddUniqueConstraintString(constraintName);
    }

    @Override
    public boolean supportsNotNullUnique() {

        return DialectContextHolder.getCurrentDialect().supportsNotNullUnique();
    }

    @Override
    public String getQueryHintString(String query, List<String> hintList) {

        return DialectContextHolder.getCurrentDialect().getQueryHintString(query, hintList);
    }

    @Override
    public String getQueryHintString(String query, String hints) {

        return DialectContextHolder.getCurrentDialect().getQueryHintString(query, hints);
    }

    @Override
    public ScrollMode defaultScrollMode() {

        return DialectContextHolder.getCurrentDialect().defaultScrollMode();
    }

    @Override
    public boolean supportsTuplesInSubqueries() {

        return DialectContextHolder.getCurrentDialect().supportsTuplesInSubqueries();
    }

    @Override
    public CallableStatementSupport getCallableStatementSupport() {

        return DialectContextHolder.getCurrentDialect().getCallableStatementSupport();
    }

    @Override
    public NameQualifierSupport getNameQualifierSupport() {

        return DialectContextHolder.getCurrentDialect().getNameQualifierSupport();
    }

    @Override
    public BatchLoadSizingStrategy getDefaultBatchLoadSizingStrategy() {

        return DialectContextHolder.getCurrentDialect().getDefaultBatchLoadSizingStrategy();
    }

    @Override
    public boolean isJdbcLogWarningsEnabledByDefault() {

        return DialectContextHolder.getCurrentDialect().isJdbcLogWarningsEnabledByDefault();
    }

    @Override
    public void augmentRecognizedTableTypes(List<String> tableTypesList) {

        DialectContextHolder.getCurrentDialect().augmentRecognizedTableTypes(tableTypesList);
    }

    @Override
    public boolean supportsPartitionBy() {
       return DialectContextHolder.getCurrentDialect().supportsPartitionBy();
    }

    @Override
    public boolean supportsNamedParameters(DatabaseMetaData databaseMetaData) throws SQLException {

        return DialectContextHolder.getCurrentDialect().supportsNamedParameters(databaseMetaData);
    }

    @Override
    public boolean supportsNationalizedTypes() {

        return DialectContextHolder.getCurrentDialect().supportsNationalizedTypes();
    }

    @Override
    public boolean supportsNonQueryWithCTE() {

        return DialectContextHolder.getCurrentDialect().supportsNonQueryWithCTE();
    }

    @Override
    public boolean supportsValuesList() {

        return DialectContextHolder.getCurrentDialect().supportsValuesList();
    }

    @Override
    public boolean supportsSkipLocked() {

        return DialectContextHolder.getCurrentDialect().supportsSkipLocked();
    }

    @Override
    public boolean supportsNoWait() {

        return DialectContextHolder.getCurrentDialect().supportsNoWait();
    }

    @Override
    public boolean isLegacyLimitHandlerBehaviorEnabled() {

        return DialectContextHolder.getCurrentDialect().isLegacyLimitHandlerBehaviorEnabled();
    }

    @Override
    public String inlineLiteral(String literal) {

        return DialectContextHolder.getCurrentDialect().inlineLiteral(literal);
    }

    @Override
    public String addSqlHintOrComment(String sql, QueryParameters parameters, boolean commentsEnabled) {

        return DialectContextHolder.getCurrentDialect().addSqlHintOrComment(sql, parameters, commentsEnabled);
    }


    public static void main(String[] args) {
        try {
            MultiDataSourceDialect.class.newInstance();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}